using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Core.Address;
using HslCommunication.Core.IMessage;
using HslCommunication.Core.Net;

namespace HslCommunication.Profinet.Melsec
{
	/// <summary>
	/// 三菱PLC通讯类，采用Qna兼容3E帧协议实现，需要在PLC侧先的以太网模块先进行配置，必须为ASCII通讯格式<br />
	/// Mitsubishi PLC communication class is implemented using Qna compatible 3E frame protocol. 
	/// The Ethernet module on the PLC side needs to be configured first. It must be ascii communication.
	/// </summary>
	/// <remarks>
	/// <inheritdoc cref="T:HslCommunication.Profinet.Melsec.MelsecMcNet" path="remarks" />
	/// </remarks>
	/// <example>
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecAscii.cs" region="Usage" title="简单的短连接使用" />
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecAscii.cs" region="Usage2" title="简单的长连接使用" />
	/// </example>
	public class MelsecMcAsciiNet : NetworkDeviceBase
	{
		/// <inheritdoc cref="P:HslCommunication.Profinet.Melsec.MelsecMcNet.NetworkNumber" />
		public byte NetworkNumber
		{
			get;
			set;
		} = 0;


		/// <inheritdoc cref="P:HslCommunication.Profinet.Melsec.MelsecMcNet.NetworkStationNumber" />
		public byte NetworkStationNumber
		{
			get;
			set;
		} = 0;


		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.#ctor" />
		public MelsecMcAsciiNet()
		{
			base.WordLength = 1;
			LogMsgFormatBinary = false;
			base.ByteTransform = new RegularByteTransform();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.#ctor(System.String,System.Int32)" />
		public MelsecMcAsciiNet(string ipAddress, int port)
		{
			base.WordLength = 1;
			IpAddress = ipAddress;
			Port = port;
			LogMsgFormatBinary = false;
			base.ByteTransform = new RegularByteTransform();
		}

		/// <inheritdoc />
		protected override INetMessage GetNewNetMessage()
		{
			return new MelsecQnA3EAsciiMessage();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.McAnalysisAddress(System.String,System.UInt16)" />
		protected virtual OperateResult<McAddressData> McAnalysisAddress(string address, ushort length)
		{
			return McAddressData.ParseMelsecFrom(address, length);
		}

		/// <inheritdoc />
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			OperateResult<McAddressData> operateResult = McAnalysisAddress(address, length);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			List<byte> list = new List<byte>();
			ushort num = 0;
			while (num < length)
			{
				ushort num2 = (ushort)Math.Min(length - num, 450);
				operateResult.Content.Length = num2;
				OperateResult<byte[]> operateResult2 = ReadAddressData(operateResult.Content);
				if (!operateResult2.IsSuccess)
				{
					return operateResult2;
				}
				list.AddRange(operateResult2.Content);
				num = (ushort)(num + num2);
				if (operateResult.Content.McDataType.DataType == 0)
				{
					operateResult.Content.AddressStart += num2;
				}
				else
				{
					operateResult.Content.AddressStart += num2 * 16;
				}
			}
			return OperateResult.CreateSuccessResult(list.ToArray());
		}

		private OperateResult<byte[]> ReadAddressData(McAddressData addressData)
		{
			byte[] mcCore = MelsecHelper.BuildAsciiReadMcCoreCommand(addressData, isBit: false);
			OperateResult<byte[]> operateResult = ReadFromCoreServer(PackMcCommand(mcCore, NetworkNumber, NetworkStationNumber));
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			OperateResult operateResult2 = CheckResponseContent(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult2);
			}
			return ExtractActualData(operateResult.Content, isBit: false);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, byte[] value)
		{
			OperateResult<McAddressData> operateResult = McAnalysisAddress(address, 0);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			byte[] mcCore = MelsecHelper.BuildAsciiWriteWordCoreCommand(operateResult.Content, value);
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(PackMcCommand(mcCore, NetworkNumber, NetworkStationNumber));
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			OperateResult operateResult3 = CheckResponseContent(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return operateResult3;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		public override async Task<OperateResult<byte[]>> ReadAsync(string address, ushort length)
		{
			OperateResult<McAddressData> addressResult = McAnalysisAddress(address, length);
			if (!addressResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(addressResult);
			}
			List<byte> bytesContent = new List<byte>();
			ushort alreadyFinished = 0;
			while (alreadyFinished < length)
			{
				ushort readLength = (ushort)Math.Min(length - alreadyFinished, 450);
				addressResult.Content.Length = readLength;
				OperateResult<byte[]> read = await ReadAddressDataAsync(addressResult.Content);
				if (!read.IsSuccess)
				{
					return read;
				}
				bytesContent.AddRange(read.Content);
				alreadyFinished = (ushort)(alreadyFinished + readLength);
				if (addressResult.Content.McDataType.DataType == 0)
				{
					addressResult.Content.AddressStart += readLength;
				}
				else
				{
					addressResult.Content.AddressStart += readLength * 16;
				}
			}
			return OperateResult.CreateSuccessResult(bytesContent.ToArray());
		}

		private async Task<OperateResult<byte[]>> ReadAddressDataAsync(McAddressData addressData)
		{
			byte[] coreResult = MelsecHelper.BuildAsciiReadMcCoreCommand(addressData, isBit: false);
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(coreResult, NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(read);
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(check);
			}
			return ExtractActualData(read.Content, isBit: false);
		}

		/// <inheritdoc />
		public override async Task<OperateResult> WriteAsync(string address, byte[] value)
		{
			OperateResult<McAddressData> addressResult = McAnalysisAddress(address, 0);
			if (!addressResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(addressResult);
			}
			byte[] coreResult = MelsecHelper.BuildAsciiWriteWordCoreCommand(addressResult.Content, value);
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(coreResult, NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return read;
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return check;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.ReadRandom(System.String[])" />
		public OperateResult<byte[]> ReadRandom(string[] address)
		{
			McAddressData[] array = new McAddressData[address.Length];
			for (int i = 0; i < address.Length; i++)
			{
				OperateResult<McAddressData> operateResult = McAddressData.ParseMelsecFrom(address[i], 1);
				if (!operateResult.IsSuccess)
				{
					return OperateResult.CreateFailedResult<byte[]>(operateResult);
				}
				array[i] = operateResult.Content;
			}
			byte[] mcCore = MelsecHelper.BuildAsciiReadRandomWordCommand(array);
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(PackMcCommand(mcCore, NetworkNumber, NetworkStationNumber));
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult2);
			}
			OperateResult operateResult3 = CheckResponseContent(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult3);
			}
			return ExtractActualData(operateResult2.Content, isBit: false);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.ReadRandom(System.String[],System.UInt16[])" />
		public OperateResult<byte[]> ReadRandom(string[] address, ushort[] length)
		{
			if (length.Length != address.Length)
			{
				return new OperateResult<byte[]>(StringResources.Language.TwoParametersLengthIsNotSame);
			}
			McAddressData[] array = new McAddressData[address.Length];
			for (int i = 0; i < address.Length; i++)
			{
				OperateResult<McAddressData> operateResult = McAddressData.ParseMelsecFrom(address[i], length[i]);
				if (!operateResult.IsSuccess)
				{
					return OperateResult.CreateFailedResult<byte[]>(operateResult);
				}
				array[i] = operateResult.Content;
			}
			byte[] mcCore = MelsecHelper.BuildAsciiReadRandomCommand(array);
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(PackMcCommand(mcCore, NetworkNumber, NetworkStationNumber));
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult2);
			}
			OperateResult operateResult3 = CheckResponseContent(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult3);
			}
			return ExtractActualData(operateResult2.Content, isBit: false);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.ReadRandomInt16(System.String[])" />
		public OperateResult<short[]> ReadRandomInt16(string[] address)
		{
			OperateResult<byte[]> operateResult = ReadRandom(address);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<short[]>(operateResult);
			}
			return OperateResult.CreateSuccessResult(base.ByteTransform.TransInt16(operateResult.Content, 0, address.Length));
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcAsciiNet.ReadRandom(System.String[])" />
		public async Task<OperateResult<byte[]>> ReadRandomAsync(string[] address)
		{
			McAddressData[] mcAddressDatas = new McAddressData[address.Length];
			for (int i = 0; i < address.Length; i++)
			{
				OperateResult<McAddressData> addressResult = McAddressData.ParseMelsecFrom(address[i], 1);
				if (!addressResult.IsSuccess)
				{
					return OperateResult.CreateFailedResult<byte[]>(addressResult);
				}
				mcAddressDatas[i] = addressResult.Content;
			}
			byte[] coreResult = MelsecHelper.BuildAsciiReadRandomWordCommand(mcAddressDatas);
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(coreResult, NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(read);
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(check);
			}
			return ExtractActualData(read.Content, isBit: false);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcAsciiNet.ReadRandom(System.String[],System.UInt16[])" />
		public async Task<OperateResult<byte[]>> ReadRandomAsync(string[] address, ushort[] length)
		{
			if (length.Length != address.Length)
			{
				return new OperateResult<byte[]>(StringResources.Language.TwoParametersLengthIsNotSame);
			}
			McAddressData[] mcAddressDatas = new McAddressData[address.Length];
			for (int i = 0; i < address.Length; i++)
			{
				OperateResult<McAddressData> addressResult = McAddressData.ParseMelsecFrom(address[i], length[i]);
				if (!addressResult.IsSuccess)
				{
					return OperateResult.CreateFailedResult<byte[]>(addressResult);
				}
				mcAddressDatas[i] = addressResult.Content;
			}
			byte[] coreResult = MelsecHelper.BuildAsciiReadRandomCommand(mcAddressDatas);
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(coreResult, NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(read);
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(check);
			}
			return ExtractActualData(read.Content, isBit: false);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcAsciiNet.ReadRandomInt16(System.String[])" />
		public async Task<OperateResult<short[]>> ReadRandomInt16Async(string[] address)
		{
			OperateResult<byte[]> read = await ReadRandomAsync(address);
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<short[]>(read);
			}
			return OperateResult.CreateSuccessResult(base.ByteTransform.TransInt16(read.Content, 0, address.Length));
		}

		/// <inheritdoc />
		public override OperateResult<bool[]> ReadBool(string address, ushort length)
		{
			OperateResult<McAddressData> operateResult = McAnalysisAddress(address, length);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			byte[] mcCore = MelsecHelper.BuildAsciiReadMcCoreCommand(operateResult.Content, isBit: true);
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(PackMcCommand(mcCore, NetworkNumber, NetworkStationNumber));
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult2);
			}
			OperateResult operateResult3 = CheckResponseContent(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult3);
			}
			OperateResult<byte[]> operateResult4 = ExtractActualData(operateResult2.Content, isBit: true);
			if (!operateResult4.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult4);
			}
			return OperateResult.CreateSuccessResult(operateResult4.Content.Select((byte m) => m == 1).Take(length).ToArray());
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, bool[] values)
		{
			OperateResult<McAddressData> operateResult = McAnalysisAddress(address, 0);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			byte[] mcCore = MelsecHelper.BuildAsciiWriteBitCoreCommand(operateResult.Content, values);
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(PackMcCommand(mcCore, NetworkNumber, NetworkStationNumber));
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			OperateResult operateResult3 = CheckResponseContent(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return operateResult3;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		public override async Task<OperateResult<bool[]>> ReadBoolAsync(string address, ushort length)
		{
			OperateResult<McAddressData> addressResult = McAnalysisAddress(address, length);
			if (!addressResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(addressResult);
			}
			byte[] coreResult = MelsecHelper.BuildAsciiReadMcCoreCommand(addressResult.Content, isBit: true);
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(coreResult, NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(read);
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(check);
			}
			OperateResult<byte[]> extract = ExtractActualData(read.Content, isBit: true);
			if (!extract.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(extract);
			}
			return OperateResult.CreateSuccessResult(extract.Content.Select((byte m) => m == 1).Take(length).ToArray());
		}

		/// <inheritdoc />
		public override async Task<OperateResult> WriteAsync(string address, bool[] values)
		{
			OperateResult<McAddressData> addressResult = McAnalysisAddress(address, 0);
			if (!addressResult.IsSuccess)
			{
				return addressResult;
			}
			byte[] coreResult = MelsecHelper.BuildAsciiWriteBitCoreCommand(addressResult.Content, values);
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(coreResult, NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return read;
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return check;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.RemoteRun" />
		public OperateResult RemoteRun()
		{
			OperateResult<byte[]> operateResult = ReadFromCoreServer(PackMcCommand(Encoding.ASCII.GetBytes("1001000000010000"), NetworkNumber, NetworkStationNumber));
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult operateResult2 = CheckResponseContent(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.RemoteStop" />
		public OperateResult RemoteStop()
		{
			OperateResult<byte[]> operateResult = ReadFromCoreServer(PackMcCommand(Encoding.ASCII.GetBytes("100200000001"), NetworkNumber, NetworkStationNumber));
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult operateResult2 = CheckResponseContent(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.RemoteReset" />
		public OperateResult RemoteReset()
		{
			OperateResult<byte[]> operateResult = ReadFromCoreServer(PackMcCommand(Encoding.ASCII.GetBytes("100600000001"), NetworkNumber, NetworkStationNumber));
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult operateResult2 = CheckResponseContent(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.ReadPlcType" />
		public OperateResult<string> ReadPlcType()
		{
			OperateResult<byte[]> operateResult = ReadFromCoreServer(PackMcCommand(Encoding.ASCII.GetBytes("01010000"), NetworkNumber, NetworkStationNumber));
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<string>(operateResult);
			}
			OperateResult operateResult2 = CheckResponseContent(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<string>(operateResult2);
			}
			return OperateResult.CreateSuccessResult(Encoding.ASCII.GetString(operateResult.Content, 22, 16).TrimEnd());
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.ErrorStateReset" />
		public OperateResult ErrorStateReset()
		{
			OperateResult<byte[]> operateResult = ReadFromCoreServer(PackMcCommand(Encoding.ASCII.GetBytes("01010000"), NetworkNumber, NetworkStationNumber));
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult operateResult2 = CheckResponseContent(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcAsciiNet.RemoteRun" />
		public async Task<OperateResult> RemoteRunAsync()
		{
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(Encoding.ASCII.GetBytes("1001000000010000"), NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return read;
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return check;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcAsciiNet.RemoteStop" />
		public async Task<OperateResult> RemoteStopAsync()
		{
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(Encoding.ASCII.GetBytes("100200000001"), NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return read;
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return check;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcAsciiNet.RemoteReset" />
		public async Task<OperateResult> RemoteResetAsync()
		{
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(Encoding.ASCII.GetBytes("100600000001"), NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return read;
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return check;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcAsciiNet.ReadPlcType" />
		public async Task<OperateResult<string>> ReadPlcTypeAsync()
		{
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(Encoding.ASCII.GetBytes("01010000"), NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<string>(read);
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return OperateResult.CreateFailedResult<string>(check);
			}
			return OperateResult.CreateSuccessResult(Encoding.ASCII.GetString(read.Content, 22, 16).TrimEnd());
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcAsciiNet.ErrorStateReset" />
		public async Task<OperateResult> ErrorStateResetAsync()
		{
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(PackMcCommand(Encoding.ASCII.GetBytes("01010000"), NetworkNumber, NetworkStationNumber));
			if (!read.IsSuccess)
			{
				return read;
			}
			OperateResult check = CheckResponseContent(read.Content);
			if (!check.IsSuccess)
			{
				return check;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		public override string ToString()
		{
			return $"MelsecMcAsciiNet[{IpAddress}:{Port}]";
		}

		/// <summary>
		/// 将MC协议的核心报文打包成一个可以直接对PLC进行发送的原始报文
		/// </summary>
		/// <param name="mcCore">MC协议的核心报文</param>
		/// <param name="networkNumber">网络号</param>
		/// <param name="networkStationNumber">网络站号</param>
		/// <returns>原始报文信息</returns>
		public static byte[] PackMcCommand(byte[] mcCore, byte networkNumber = 0, byte networkStationNumber = 0)
		{
			byte[] array = new byte[22 + mcCore.Length];
			array[0] = 53;
			array[1] = 48;
			array[2] = 48;
			array[3] = 48;
			array[4] = SoftBasic.BuildAsciiBytesFrom(networkNumber)[0];
			array[5] = SoftBasic.BuildAsciiBytesFrom(networkNumber)[1];
			array[6] = 70;
			array[7] = 70;
			array[8] = 48;
			array[9] = 51;
			array[10] = 70;
			array[11] = 70;
			array[12] = SoftBasic.BuildAsciiBytesFrom(networkStationNumber)[0];
			array[13] = SoftBasic.BuildAsciiBytesFrom(networkStationNumber)[1];
			array[14] = SoftBasic.BuildAsciiBytesFrom((ushort)(array.Length - 18))[0];
			array[15] = SoftBasic.BuildAsciiBytesFrom((ushort)(array.Length - 18))[1];
			array[16] = SoftBasic.BuildAsciiBytesFrom((ushort)(array.Length - 18))[2];
			array[17] = SoftBasic.BuildAsciiBytesFrom((ushort)(array.Length - 18))[3];
			array[18] = 48;
			array[19] = 48;
			array[20] = 49;
			array[21] = 48;
			mcCore.CopyTo(array, 22);
			return array;
		}

		/// <summary>
		/// 从PLC反馈的数据中提取出实际的数据内容，需要传入反馈数据，是否位读取
		/// </summary>
		/// <param name="response">反馈的数据内容</param>
		/// <param name="isBit">是否位读取</param>
		/// <returns>解析后的结果对象</returns>
		public static OperateResult<byte[]> ExtractActualData(byte[] response, bool isBit)
		{
			if (isBit)
			{
				return OperateResult.CreateSuccessResult((from m in response.RemoveBegin(22)
					select (byte)((m != 48) ? 1 : 0)).ToArray());
			}
			return OperateResult.CreateSuccessResult(MelsecHelper.TransAsciiByteArrayToByteArray(response.RemoveBegin(22)));
		}

		/// <summary>
		/// 检查反馈的内容是否正确的
		/// </summary>
		/// <param name="content">MC的反馈的内容</param>
		/// <returns>是否正确</returns>
		public static OperateResult CheckResponseContent(byte[] content)
		{
			ushort num = Convert.ToUInt16(Encoding.ASCII.GetString(content, 18, 4), 16);
			if (num != 0)
			{
				return new OperateResult(num, MelsecHelper.GetErrorDescription(num));
			}
			return OperateResult.CreateSuccessResult();
		}
	}
}
